package de.tuberlin.dima.minidb.test;


import java.util.ResourceBundle;

import de.tuberlin.dima.minidb.api.ExtensionFactory;
import de.tuberlin.dima.minidb.parser.ParseException;
import de.tuberlin.dima.minidb.parser.ParsedQuery;
import de.tuberlin.dima.minidb.parser.ParserFactory;
import de.tuberlin.dima.minidb.parser.SQLParser;

import junit.framework.TestCase;


/**
 * The private test case for the parser (Exercise 1)
 * 
 * @author Stephan Ewen (sewen@cs.tu-berlin.de)
 */
public class Ex01Parser extends TestCase
{
	/**
	 * Queries that must be parsed successfully
	 */
	private String[] runableQueries = {
			
			"select avg(p.a) as avg_age, maX(pp.share) as maxShare, p.customer as customer " +
			"froM worker w, project p, participates pp " +
			"WHERE w.pers_id = 8 and pp.proj_id = p.proj_id " +
			"and w.age > 20 and p.status   =\"closed\" " +
			"GROUp BY  p.customer " +
			"having avg_age <= 50 " +
			"order by maxShare desc",
			
	/*
			"delete from tab t1 where t1.age >= a.a and b.b = c.c",
			
			"seleCt t1.first_name as fn, t1.last_name as ln, max(proj.priority) as prio " +
			"FROM person t1, project proj, participates pp " +
			"WHERE t1.pers_id = pp.pers_id anD pp.proj_id = proj.proj_id " +
			"GROUp by t1.first_name, t2.last_name " +
			"having fn >= 4 " +
			"order by prio desc",

			
			"seleCt t1.first_name as fn, t1.last_name as ln, max(proj.priority) as prio " +
		"FROM person t1, project proj, participates pp " +
		"WHERE t1.pers_id = pp.pers_id anD pp.proj_id = proj.proj_id ",
		
		"Delete from tab t1",
		
		
		"INSERT into tabl2 SELECT ze.tz as tz FROM t6 ze group by t.a having tz = \"hallo\"",
		
		"Insert into some_table values (2, 3, \"anything\"), (\"string\", \"after\", \"string\")"
		*/
	};

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#setUp()
	 */
	protected void setUp() throws Exception
	{
		super.setUp();
		
		// first check system variables
		String extensionClassName = System.getProperty("de.tuberlin.dima.minidb.extension");
		
		// if not found, try properties file
		if (extensionClassName == null) {
			try {
				ResourceBundle bundle = ResourceBundle.getBundle("resources.test");
				extensionClassName = bundle.getString("ExtensionFactory.impl");
			}
			catch (Exception ex) {
				// ignore
			}
		}
		
		if (extensionClassName == null || extensionClassName.length() == 0) {
			System.err.println("No extension class name set!");
			System.exit(2);
		}
		
		ExtensionFactory.init(extensionClassName);
	}

	/* (non-Javadoc)
	 * @see junit.framework.TestCase#tearDown()
	 */
	protected void tearDown() throws Exception
	{
		super.tearDown();
	}
	
	
	public void testParser() throws Exception
	{
		// check all queries
		for (int i = 0; i < runableQueries.length; i++) 
		{
			ParsedQuery reference = null;
			
			try {
				SQLParser refParser = new ReferenceParser(runableQueries[i]);
				reference = refParser.parse();
			}
			catch (ParseException pex) {
				System.err.println("\n\nReference parser could not parse statement " + i);
				System.err.println(pex.getMessage());
				System.err.println("\n");
				continue;
			}
			
			try {
				SQLParser parser = ParserFactory.createParser(runableQueries[i]);
				ParsedQuery query = parser.parse();
				
				System.out.println(query.getNodeContents());
				
				assertTrue(query != null);
				assertTrue(query.isIdenticalTo(reference));
			}
			catch (ParseException pex) {
				System.err.println(pex.getMessage());
				assertTrue(false);
			}
		}
	}

}
